
//
// 120512 - AH - (Midtun) Created.
//

package org.socratons.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;

import org.japril.jutil.CharArrayPrintWriter;

/**
 * <p>
 *   Object that compiles Socratons service protocol XML.
 * </p>
 * @author Arne Halvorsen (AH)
 * @author Laetitia Le Chatton (LLC)
 */
public final class SocratonsXmlProtocolCompiler 
{
  private String m_method=null;
  
  private List<SocData> m_socs=new ArrayList<SocData>();
  
  /**
   * <p>
   *   Constructor.
   * </p>
   */
  public SocratonsXmlProtocolCompiler(){}
  
  /**
   * <p>
   *   Sets method.
   * </p>
   * @param m Method name.
   * @return {@code this}.
   */
  public SocratonsXmlProtocolCompiler method(String m)
  { 
    m_method=m; 
    return this; 
  }
  
  /**
   * <p>
   *   Adds 
   *   {@link SocData}.
   * </p>
   * @param s {@code Socraton}.
   * @return {@code this}.
   */
  public SocratonsXmlProtocolCompiler socraton(SocData s)
  {
    m_socs.add(s);
    return this;
  }
  
  /**
   * <p>
   *   Adds
   *   {@link SocData} objects.
   * </p>
   * @param socs Objects to add.
   * @return {@code this}.
   */
  public SocratonsXmlProtocolCompiler socratons(Collection<SocData> socs)
  {
    m_socs.addAll(socs);
    return this;
  }
  
  /**
   * <p>
   *   Compiles.
   * </p>
   * @return XML.
   */
  public String compile()
  {
    CharArrayPrintWriter capw=new CharArrayPrintWriter();
    
    StringBuilder sb=new StringBuilder();
    
    capw.println("<?xml version='1.0'?>");
    
    sb.append("<socratons");
    if (m_method!=null) sb.append(" method='").append(m_method).append("'");
    
    if (m_socs.isEmpty()) sb.append(" />");
    else                  sb.append(">");
    
    capw.println(sb);
    
    for (SocData s : m_socs)
    {
      String who=s.who;
      
      if (s!=null)
      {
        sb.setLength(0);
        sb.append("  <socraton id='").append(s.id).append("'");
        if (who!=null) sb.append(" who='").append(who).append("' >");
        capw.println(sb);
        
        for (Entry<String, List<String>> e : s.bisons.entrySet())
        {
          String ctx=e.getKey();
          List<String> bisons=e.getValue();
          
          sb.setLength(0);
          sb.append("    <context name='").append(ctx).append("'>");
          capw.println(sb);
          
          for (String data : bisons)
          {
            sb.setLength(0);
            sb.append("      <bison>").append(data).append("</bison>");
            capw.println(sb);
          }
          
          capw.println("    </context>");
        }
        
        capw.println("  </socraton>");
      }
    }    
      
    capw.println("</socratons>");
    
    return capw.toString();
  }
  
  /**
   * <p>
   *   Simple demo/test program.
   * </p>
   * @param args Command line arguments, not used.
   */
  /*
  public static void main(String[] args)
  {
    Socraton s0=new Socraton("Arne");
    s0.addBison("photo", new Bison("Nikon"));
    s0.addBison("food", new Bison("Horror"));
    
    Socraton s1=new Socraton("Laetitia");
    s1.addBison("art", new Bison("painting"));
    s1.addBison("art", new Bison("CM"));
    s1.addBison("food", new Bison("Gourmet"));
    
    SocratonsXmlProtocolCompiler compiler=new SocratonsXmlProtocolCompiler();
    
    compiler.method("update")
            .socraton(s0).who("test-program")
            .socraton(s1).who("something-else");
    
    String xml=compiler.compile();
    
    System.out.println(xml);
  }
  */
}
